package com.jiayou.config.vertx.handler.jwt

import com.jiayou.config.vertx.VertxApplication
import io.vertx.core.AsyncResult
import io.vertx.core.Handler
import io.vertx.core.json.JsonArray
import io.vertx.core.json.JsonObject
import io.vertx.ext.auth.User
import io.vertx.ext.web.RoutingContext
import org.springframework.stereotype.Component
import org.springframework.util.AntPathMatcher

/**
@author lishuang
@data   2021-06-25  11:18:57
@info   jwt权限认证处理器
 */
@Component
open class JwtPermissionsHandler : Handler<RoutingContext> {
    final override fun handle(routingContext: RoutingContext) = doHandle(routingContext)

    private val antPathMatcher = AntPathMatcher()

    /**
     * 鉴权处理
     * @param routingContext 路由上下文对象
     */
    open fun doHandle(routingContext: RoutingContext) {
        val currentPath = routingContext.request().path()

        if ("/*" in VertxApplication.filtrationURL) {
            routingContext.next()
            return
        }
        for (filtrationURLItem in VertxApplication.filtrationURL) {
            if (antPathMatcher.match(filtrationURLItem, currentPath)) {
                routingContext.next()
                return
            }
        }

        if (routingContext.user() != null) {
            val permissions = routingContext.user().principal().map["permissions"] as JsonArray?
            if (permissions != null) {
                if (permissions.contains("*")) {
                    routingContext.next()
                    return
                } else {
                    permissions.forEach { permissionsItem ->
                        if (permissionsItem == routingContext.request().path()) {
                            successHandle(routingContext)
                            routingContext.next()
                            return
                        }
                    }
                }
            }
        }
        failHandle(routingContext)
    }

    /**
     * 权限验证成功回调
     * @param routingContext 路由上下文对象
     */
    open fun successHandle(routingContext: RoutingContext) {

    }

    /**
     * 权限验证失败回调
     * @param routingContext 路由上下文对象
     */
    open fun failHandle(routingContext: RoutingContext) {
        routingContext.response().statusCode = 403
        routingContext.response().putHeader("Content-Type", "application/json")
        routingContext.response().end(JsonObject().put("code", 403).put("message", "当前没有该资源的访问权限 ！").put("data", null).encode())
    }

}